package com.fzrskj.cloud.sdk.mini.server;

import com.alibaba.fastjson.JSONObject;
import com.restphp.java.utils.http.client.RestClientUtils;
import com.restphp.java.utils.http.consts.HttpMethod;
import com.restphp.java.utils.string.core.StringUtils;
import com.restphp.java.utils.string.encrypt.EncryptMd5Utils;

import java.util.HashMap;
import java.util.Map;

/**
 * 微服务SDK操作类础类.
 * Created by sofical on 2020/9/28.
 */
public class MiniServerBase {
    /**
     * 认证API地址.
     */
    private String authApi;
    /**
     * 认证服务host.
     */
    private String host;
    /**
     * Api 名称.
     */
    private String apiName;
    /**
     * 认证密钥.
     */
    private String secretKey;

    /**
     * 微服务编码.
     */
    private String appCode;

    protected static RestClientUtils clientUtils = new RestClientUtils();

    /**
     * construct.
     * @param miniServerConfig 微服务配置.
     * @param apiName 接口名称.
     */
    public MiniServerBase (MiniServerConfig miniServerConfig, String apiName) {
        this.appCode = miniServerConfig.getAppCode();
        this.authApi = miniServerConfig.getAuthAddress() + "/web.do?fn=" + apiName;
        this.secretKey = miniServerConfig.getSecretKey();
        if (!authApi.contains("://")) {
            throw new RuntimeException("SDK init error: authApi is error, because of without request scheme.");
        }
        if (authApi.indexOf("/", authApi.indexOf("://") + 3) < 0) {
            throw new RuntimeException("SDK init error: authApi is error, because of without api name.");
        }

        this.host = authApi.substring(authApi.indexOf("://") + 3, authApi.indexOf("/", authApi.indexOf("://") + 3));

        this.apiName = apiName;
    }

    /**
     * 获取认证API地址。
     * @return 认证API地址。
     */
    public String getAuthApi() {
        return this.authApi;
    }

    /**
     * 获取认证服务host.
     * @return 认证服务host.
     */
    public String getHost() {
        return this.host;
    }

    /**
     * 获取Api 名称.
     * @return Api 名称.
     */
    public String getApiName() {
        return apiName;
    }

    /**
     * 获取认证密钥.
     * @return 认证密钥.
     */
    public String getSecretKey() {
        return secretKey;
    }

    /**
     * 获取微服务编码.
     * @return 微服务编码.
     */
    public String getAppCode() {
        return this.appCode;
    }

    /**
     * 创建认证凭证.
     * @return 认证信息.
     */
    protected AuthSn createAuthSn() {
        AuthSn authSn = new AuthSn();
        String nonce = System.currentTimeMillis() + StringUtils.randomEnChar(6);
        String snSource = this.getHost() + "\n" + HttpMethod.POST.name().toUpperCase() + "\n" + this.getApiName() + "\n" + nonce + "" + this.getSecretKey();
        String sn = EncryptMd5Utils.encode(snSource);
        authSn.setNonce(nonce);
        authSn.setSn(sn);
        String snStr = "id=" + this.getAppCode() + ";nonce=" + nonce + ";sn=" + sn;
        Map<String, String> complete = new HashMap<>();
        complete.put("auth", snStr);
        complete.put("Content-Type", "application/x-www-form-urlencoded");
        authSn.setComplete(complete);
        return authSn;
    }

    /**
     * 请求数据格式化.
     * @param requestData 请求数据.
     * @return 格式化后的请求数据.
     */
    protected String formatParam (Map requestData) {
        return "p=" + JSONObject.toJSONString(requestData);
    }

    /**
     * 请求云平台数据.
     * @return 请求结果.
     */
    protected MiniServerResult post (Map requestData) {
        //生成认证信息
        AuthSn authSn = createAuthSn();
        return clientUtils.requestStringData(HttpMethod.POST, this.getAuthApi(), null, authSn.getComplete(), formatParam(requestData), MiniServerResult.class);
    }
}
